# coding=utf-8
import os
import csv
import struct
from dataAnlysis import dataList
import binascii
import time
import datetime
import copy
import sys

sys.path.append("./package")
from const import const
from log import Log
from MysqlHelp import _MySqlHelper

current_target_path = ""
mysql_helper = None


def creatMysqlCon(name):
    global mysql_helper
    mysql_helper = _MySqlHelper(name)
    print(mysql_helper)


# 获取文件夹下所有文件
def get_all_file(rawdir):
    allfilelist = os.listdir(rawdir)
    for f in allfilelist:
        filepath = os.path.join(rawdir, f)
        if os.path.isdir(filepath):
            get_all_file(filepath)
        else:
            file_list.append(filepath)


# tools
def dec_hex(str1):
    a = str(hex(str1))
    b = a.replace("0x", '')
    if len(b) == 1:
        b = "0" + b
    return b.upper()


# onceDataForDictArray
def onceDataForDictArray(array, file_dat, index):
    writerArrays = []
    for dic in array:
        if "type" not in dic:
            file_dat.seek(dic["offset"] + index, 0)
            dat = file_dat.read(dic["len"])
            b = struct.unpack(dic["str"], dat)

            if "date" in dic:
                if dic["date"] == "unix":
                    timeStamp = b[0]
                    timeArray = time.gmtime(timeStamp)
                    otherStyleTime = time.strftime("%Y%m%d%H%M%S", timeArray)
                    b = (otherStyleTime,)
                if dic["date"] == "localtime":
                    timeStamp = b[0]
                    timeArray = time.localtime(timeStamp)
                    otherStyleTime = time.strftime("%Y%m%d%H%M%S", timeArray)
                    b = (otherStyleTime,)
                if dic["date"] == "five":
                    timeStamp = b[0]
                    d1 = datetime.datetime(1899, 12, 31)
                    if timeStamp < 80000:
                        d3 = d1 + datetime.timedelta(timeStamp)
                        b = datetime.datetime.strftime(d3, "%Y%m%d")
        else:
            if dic["type"] == "BCD":
                file_dat.seek(dic["offset"] + index, 0)
                dat = file_dat.read(dic["len"])
                b = str(binascii.b2a_hex(dat), encoding="utf-8").upper()
                b = (b,)
            elif dic["type"] == "ASCII":
                file_dat.seek(dic["offset"] + index, 0)
                dat = file_dat.read(dic["len"])
                b = str(dat, encoding="utf-8")
            elif dic["type"] == "Dur":
                file_dat.seek(dic["offset"] + index, 0)
                dat = file_dat.read(dic["len"])
                b = struct.unpack(dic["str"], dat)
                if b[0]:
                    b = bin(b[0]).replace('0b', '')
                    lackZero = 16 - len(b)
                    for i in range(lackZero):
                        b = "0" + b
                    num = int(b[4:], 2)
                    typeNum = int(b[0:4], 2)
                    typeStr = ""
                    if typeNum == 1:
                        typeStr = u"秒"
                    elif typeNum == 2:
                        typeStr = u"分钟"
                    elif typeNum == 3:
                        typeStr = u"小时"
                    elif typeNum == 4:
                        typeStr = u"日"
                    elif typeNum == 5:
                        typeStr = u"周"
                    elif typeNum == 7:
                        typeStr = u"年"
                    else:
                        typeStr = ""
                    b = "%d%s" % (num, typeStr)

        if type(b) is str:
            tempData = "\t" + b
            writerArrays.append(tempData)
        else:
            for tempData in b:
                if type(tempData) is str:
                    tempData = "\t" + tempData
                    writerArrays.append(tempData)
                else:
                    writerArrays.append(tempData)

    return writerArrays

# onceDataForDictValue 按字典列表读取解析并返回字典列表（[key,value]）
def onceDataForDictValue(array, file_dat, index):
    writerArrays = []
    tempIndex = index
    for dic in array:
        if "type" not in dic:
            file_dat.seek(dic["offset"] + index, 0)
            dat = file_dat.read(dic["len"])
            b = struct.unpack(dic["str"], dat)

            if "date" in dic:
                if dic["date"] == "unix":
                    timeStamp = b[0]
                    timeArray = time.gmtime(timeStamp)
                    otherStyleTime = time.strftime("%Y%m%d%H%M%S", timeArray)
                    b = (otherStyleTime,)
                if dic["date"] == "localtime":
                    timeStamp = b[0]
                    timeArray = time.localtime(timeStamp)
                    otherStyleTime = time.strftime("%Y%m%d%H%M%S", timeArray)
                    b = (otherStyleTime,)
                if dic["date"] == "five":
                    timeStamp = b[0]
                    d1 = datetime.datetime(1899, 12, 31)
                    if timeStamp < 80000:
                        d3 = d1 + datetime.timedelta(timeStamp)
                        b = datetime.datetime.strftime(d3, "%Y%m%d")
        else:
            if dic["type"] == "BCD":
                file_dat.seek(dic["offset"] + index, 0)
                dat = file_dat.read(dic["len"])
                b = str(binascii.b2a_hex(dat), encoding="utf-8").upper()
                b = (b,)
            elif dic["type"] == "ASCII":
                file_dat.seek(dic["offset"] + index, 0)
                dat = file_dat.read(dic["len"])
                b = str(dat, encoding="utf-8")
            elif dic["type"] == "Dur":
                file_dat.seek(dic["offset"] + index, 0)
                dat = file_dat.read(dic["len"])
                b = struct.unpack(dic["str"], dat)
                if b[0]:
                    b = bin(b[0]).replace('0b', '')
                    lackZero = 16 - len(b)
                    for i in range(lackZero):
                        b = "0" + b
                    num = int(b[4:], 2)
                    typeNum = int(b[0:4], 2)
                    typeStr = ""
                    if typeNum == 1:
                        typeStr = u"秒"
                    elif typeNum == 2:
                        typeStr = u"分钟"
                    elif typeNum == 3:
                        typeStr = u"小时"
                    elif typeNum == 4:
                        typeStr = u"日"
                    elif typeNum == 5:
                        typeStr = u"周"
                    elif typeNum == 7:
                        typeStr = u"年"
                    else:
                        typeStr = ""
                    b = "%d%s" % (num, typeStr)

        tempIndex = tempIndex	+ dic["len"]
        if type(b) is str:
            tempData = b
            writerArrays.append({"name": dic["name"] ,"value": tempData})
        else:
            for tempData in b:
                if type(tempData) is str:
                    tempData = tempData
                    writerArrays.append({"name": dic["name"] ,"value": tempData})
                else:
                    writerArrays.append({"name": dic["name"] ,"value": tempData})

    return writerArrays,tempIndex


# ============多文件 分文件解析============
def readFileOne(array, file_dat, index, fileName, sql):
    writerArrays = onceDataForDictArray(array, file_dat, index)
    writerArrays.insert(0, "\t" + fileName)

    file_dat.seek(3 + index, 0)
    dat = file_dat.read(4)
    b = str(binascii.b2a_hex(dat), encoding="utf-8")

    global current_target_path
    new_dir = os.path.join(current_target_path, fileName[0:5] + b + '.csv')
    flag = os.path.isfile(new_dir)
    file_csv = open(new_dir, 'a+', newline='', encoding="utf-8-sig")  # 创建/修改新文件
    file_csv_writer = csv.writer(file_csv)

    if not flag:
        nameArray = ["文件名"]
        for dicts in array:
            if isinstance(dicts["name"], str):
                nameArray.append(dicts["name"])
            else:
                for strSingle in dicts["name"]:
                    nameArray.append(strSingle)
        file_csv_writer.writerow(nameArray)

    file_csv_writer.writerow(writerArrays)
    if sql:
        mysql_helper.execute(sql, writerArrays)
        pass
    file_csv.close()


def judgeDataType(fileName):
    typeFileSubStr = fileName[0:2]  # 前两位 子类型
    typeFileStr = fileName[2:4]  # 后两位 主类型
    typeFileStrCode = fileName[0:4]
    arrayS = []
    sql = ''
    if typeFileStrCode == "0103":
        arrayS = dataList.TxnCardIssue()
        sql = const.SQL0103
        return arrayS, sql

    if typeFileStrCode == "0121":
        arrayS = dataList.TxnCardFeeReverse()
        sql = const.SQL0121
        return arrayS, sql


    if typeFileStrCode == "0120":
        arrayS = dataList.TxnCardDepositReceiptReverse()
        sql = const.SQL0120
        return arrayS, sql
    ## Eric 20211113 append '034F','0350','0351'
    if typeFileStrCode == "034F":
        arrayS = dataList.TxnProductMultirideIssueReverse()
        sql = const.SQL034F
        return arrayS, sql
    if typeFileStrCode == "0350":
        arrayS = dataList.TxnProductPassIssueReverse()
        sql = const.SQL0350
        return arrayS, sql
    if typeFileStrCode == "0351":
        arrayS = dataList.TxnProductPurseIssueReverse()
        sql = const.SQL0351
        return arrayS, sql

    if typeFileSubStr == "24":
        if typeFileStrCode == "2401":
            arrayS = dataList.erWeiMaJinZhanJiaoYi()
            sql = const.SQL2401
        if typeFileStrCode == "2402":
            arrayS = dataList.erWeiMaChuZhanJiaoYi()
            sql = const.SQL2402
        if typeFileStrCode == "2403":
            arrayS = dataList.erWeiMaBuDengJiaoYi()
            sql = const.SQL2403
    else:
        if typeFileStr == "21":
            arrayS = dataList.changAnTongFeiLianJiList()
            sql = const.SQL0C21
        elif typeFileStr == "08":
            arrayS = dataList.changAnTongShouChongList()
            sql = const.SQL0E08
        elif typeFileStr == "22":
            arrayS = dataList.jiaoTongKaBenDiKaFeiLianJi()
            sql = const.SQL0C22
        elif typeFileStr == "23":
            arrayS = dataList.jiaoTongKaYiDiKaFeiLianJi()
            sql = const.SQL0C23
        elif typeFileStr == "03":
            arrayS = dataList.TxnProductMultirideIssue()
            sql = const.SQL0303
        elif typeFileStr == "01":
            arrayS = dataList.TxnProductPurseIssue()
            sql = const.SQL0301
        elif typeFileStr == "79":
            arrayS = dataList.TxnProductMultirideExitTicketIssue()
            sql = const.SQL0379
        elif typeFileStr == "78":
            arrayS = dataList.TxnProductMultirideCompensationFare()
            sql = const.SQL0378
        elif typeFileStr == "77":
            arrayS = dataList.TxnProductPassCompensationFare()
            sql = const.SQL0377
        elif typeFileStr == "76":
            arrayS = dataList.TxnProductPurseCompensationFare()
            sql = const.SQL0376
        elif typeFileStr == "1A":
            arrayS = dataList.TxnProductPurseRefund()
            sql = const.SQL031A
        elif typeFileStr == "5A":
            arrayS = dataList.TxnProductMultirideUseOnEntry()
        elif typeFileStr == "59":
            arrayS = dataList.TxnProductPassUseOnEntry()
        elif typeFileStr == "58":
            arrayS = dataList.TxnProductPurseUseOnEntry()
        elif typeFileStr == "5D":
            arrayS = dataList.TxnProductMultirideUseOnExit()
            sql = const.SQL035D
        elif typeFileStr == "5C":
            arrayS = dataList.TxnProductPassUseOnExit()
            sql = const.SQL035C
        elif typeFileStr == "5B":
            arrayS = dataList.TxnProductPurseUseOnExit()
            sql = const.SQL035B
        elif typeFileStr == "70":
            arrayS = dataList.TxnProductDelayMultirideUseOnEntry()
        elif typeFileStr == "72":
            arrayS = dataList.TxnProductDelayPassUseOnEntry()
        elif typeFileStr == "74":
            arrayS = dataList.TxnProductDelayPurseUseOnEntry()
        elif typeFileStr == "71":
            arrayS = dataList.TxnProductDelayMultirideUseOnExit()
            sql = const.SQL0371
        elif typeFileStr == "73":
            arrayS = dataList.TxnProductDelayPassUseOnExit()
            sql = const.SQL0373
        elif typeFileStr == "75":
            arrayS = dataList.TxnProductDelayPurseUseOnExit()
            sql = const.SQL0375

    return arrayS, sql

def judgerReconciliationDataType(fileName):
    typeFileSubStr = fileName[1:3]  # 前两位 票卡类型
    typeFileStr = fileName[3:5]  # 后两位 数据类型
    typeFileStrCode = fileName[1:5]
    print('typeFileStr:%s'%typeFileStr)
    print('typeFileStrCode:%s'%typeFileStrCode)
    arrayS = []
    sql = ''
    DataLength = 0
    if typeFileStr == "01":
        arrayS = dataList.ReconciliationScopeData()
        DataLength = 16
        if typeFileStrCode == "F101":
            sql = const.SQLF101
        elif typeFileStrCode == "F201":
            sql = const.SQLF201
        elif typeFileStrCode == "F301":
            sql = const.SQLF301
        elif typeFileStrCode == "F401":
            sql = const.SQLF401

    if typeFileStr == "02":
        arrayS = dataList.ReconciliationErrorDetail()
        DataLength = 86
        if typeFileStrCode == "F102":
            sql = const.SQLF102
        elif typeFileStrCode == "F202":
            sql = const.SQLF202
        elif typeFileStrCode == "F302":
            sql = const.SQLF302
        elif typeFileStrCode == "F402":
            sql = const.SQLF402

    if typeFileStr == "03":
        arrayS = dataList.ReconciliationAdjustDetail()
        DataLength = 60
        if typeFileStrCode == "F103":
            sql = const.SQLF103
        elif typeFileStrCode == "F203":
            sql = const.SQLF203
        elif typeFileStrCode == "F303":
            sql = const.SQLF303
        elif typeFileStrCode == "F403":
            sql = const.SQLF403

    if typeFileStr == "04":
        arrayS = dataList.ReconciliationStatData()
        DataLength = 42
        if typeFileStrCode == "F104":
            sql = const.SQLF104
        elif typeFileStrCode == "F204":
            sql = const.SQLF204
        elif typeFileStrCode == "F304":
            sql = const.SQLF304
        elif typeFileStrCode == "F404":
            sql = const.SQLF404

    else:
        if typeFileStrCode == "F105":
            arrayS = dataList.ReconciliationQrTicketError()
            DataLength = 103
            sql = const.SQLF105
        elif typeFileStrCode == "F106":
            arrayS = dataList.ReconciliationCleanData()
            DataLength = 74
            sql = const.SQLF106
        elif typeFileStrCode == "F107":
            arrayS = dataList.ReconciliationCashIncome()
            DataLength = 38
            sql = const.SQLF107

    return arrayS, sql, DataLength


def analysisFile(source_path, target_path, line, typeStr, dbName):
    global current_target_path
    global file_list
    global log

    creatMysqlCon(dbName)

    logName = line + '#' + typeStr
    rq = time.strftime('%Y%m%d', time.localtime(time.time()))
    log = Log(logName, rq)
    file_list = []
    current_target_path = target_path
    get_all_file(source_path)
    # file_list = os.listdir(source_path)
    for dir_path in file_list:
        _, files = os.path.split(dir_path)
        # dir_path = os.path.join(source_path, files)
        # 分离文件名和文件类型
        file_name = os.path.splitext(files)[0]  # 文件名
        file_type = os.path.splitext(files)[1]  # 文件类型
        # 2020-07-10 chenchao
        if file_type != '.dat':
            file_type = '.dat'

        ignoreDataCount = 0
        # 将.dat文件转为.csv文件
        if file_type == '.dat':  # 可切换为.xls等
            file_dat = open(dir_path, 'rb')  # 读取原文件

            # 判断数据类型
            array, sql = judgeDataType(file_name)
            #if len(array) == 0:
            if array is None or len(array) == 0:
                log.error('无对应类型fileName: %s' % file_name)
                # print('fileName%s', file_name)
                continue

            file_dat.seek(7, 0)
            lenDat = file_dat.read(2)
            lenThs = struct.unpack("<H", lenDat)
            file_dat.seek(0, 0)
            lenDat = file_dat.read()
            count = len(lenDat) // lenThs[0]

            for i in range(count):
                try:
                    readFileOne(array, file_dat, i * lenThs[0], file_name, sql)
                except Exception as e:
                    print(file_name)
                    print(e)
            file_dat.close()
    global mysql_helper
    mysql_helper.closeCon()

# ================有18字节头=======================


def analysisForDict(listS, file_dat, index, headData, fileName):
    arrayS = []
    sql = ''
    if listS[1] == 1 and listS[0] == 36:
        arrayS = dataList.erWeiMaJinZhanJiaoYi()
        sql = const.SQL2401
    if listS[1] == 2 and listS[0] == 36:
        arrayS = dataList.erWeiMaChuZhanJiaoYi()
        sql = const.SQL2402
    if listS[1] == 3 and listS[0] == 36:
        arrayS = dataList.erWeiMaBuDengJiaoYi()
        sql = const.SQL2403
    # if listS[1] == 1 and listS[0] == 3:
    #     arrayS = dataList.TxnProductPurseIssue()
    #     sql = const.SQL0301
    if listS[1] == 33 and (
            listS[0] == 12 or listS[0] == 13 or listS[0] == 14 or listS[0] == 15 or listS[0] == 17 or listS[0] == 22 or
            listS[0] == 33):
        arrayS = dataList.changAnTongFeiLianJiList()
        sql = const.SQL0C21
    if listS[1] == 8 and (listS[0] == 14 or listS[0] == 15):
        arrayS = dataList.changAnTongShouChongList()
        sql = const.SQL0E08
    if listS[1] == 33 and (listS[0] == 17 or listS[0] == 22):
        file_dat.seek(7 + index, 0)
        dat = file_dat.read(2)
        b = struct.unpack("<H", dat)
        if b == 151:
            arrayS = dataList.changAnTongShouChongList()
            sql = const.SQL0E08
    if listS[1] == 34 and (
            listS[0] == 14 or listS[0] == 12 or listS[0] == 13 or listS[0] == 15 or listS[0] == 22 or listS[0] == 17):
        arrayS = dataList.jiaoTongKaBenDiKaFeiLianJi()
        sql = const.SQL0C22
        #print('SQL0C22，listS[0] = ' + str(listS[0]))
    if listS[1] == 35 and (
            listS[0] == 14 or listS[0] == 12 or listS[0] == 13 or listS[0] == 15 or listS[0] == 22 or listS[0] == 17):
        arrayS = dataList.jiaoTongKaYiDiKaFeiLianJi()
        sql = const.SQL0C23
        #print('SQL0C23，listS[0] = ' + str(listS[0]))
    if listS[1] == 3 and listS[0] == 1:
        arrayS = dataList.TxnCardIssue()
        sql = const.SQL0103
    if listS[1] == 3 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideIssue()
        sql = const.SQL0303
    if listS[1] == 2 and listS[0] == 3:
        arrayS = dataList.TxnProductPassIssue()
        sql = const.SQL0302
    if listS[1] == 1 and listS[0] == 3:
        arrayS = dataList.TxnProductPurseIssue()
        sql = const.SQL0301
        #print('SQL0301 = ' + sql)
    if listS[1] == 121 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideExitTicketIssue()
        sql = const.SQL0379
    if listS[1] == 12 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideAdd()
        sql = const.SQL030C
    if listS[1] == 120 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideCompensationFare()
        sql = const.SQL0378
    if listS[1] == 119 and listS[0] == 3:
        arrayS = dataList.TxnProductPassCompensationFare()
        sql = const.SQL0377
    if listS[1] == 118 and listS[0] == 3:
        arrayS = dataList.TxnProductPurseCompensationFare()
        sql = const.SQL0376
    if listS[1] == 26 and listS[0] == 3:
        arrayS = dataList.TxnProductPurseRefund()
        sql = const.SQL031A
    if listS[1] == 9 and listS[0] == 81:
        arrayS = dataList.MoneyTicketBox()
        sql = const.SQL0981
    if listS[1] == 4 and listS[0] == 70:
        arrayS = dataList.TvmFaultRefund()
        sql = const.SQL7004
    if listS[1] == 5 and listS[0] == 70:
        arrayS = dataList.BomFaultRefund()
        sql = const.SQL7005
    if listS[1] == 90 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideUseOnEntry()
    if listS[1] == 89 and listS[0] == 3:
        arrayS = dataList.TxnProductPassUseOnEntry()
    if listS[1] == 88 and listS[0] == 3:
        arrayS = dataList.TxnProductPurseUseOnEntry()
    if listS[1] == 93 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideUseOnExit()
        sql = const.SQL035D
    if listS[1] == 92 and listS[0] == 3:
        arrayS = dataList.TxnProductPassUseOnExit()
        sql = const.SQL035C
    if listS[1] == 91 and listS[0] == 3:
        arrayS = dataList.TxnProductPurseUseOnExit()
        sql = const.SQL035B
    if listS[1] == 112 and listS[0] == 3:
        arrayS = dataList.TxnProductDelayMultirideUseOnEntry()
    if listS[1] == 114 and listS[0] == 3:
        arrayS = dataList.TxnProductDelayPassUseOnEntry()
    if listS[1] == 116 and listS[0] == 3:
        arrayS = dataList.TxnProductDelayPurseUseOnEntry()
    if listS[1] == 113 and listS[0] == 3:
        arrayS = dataList.TxnProductDelayMultirideUseOnExit()
        sql = const.SQL0371
    if listS[1] == 115 and listS[0] == 3:
        arrayS = dataList.TxnProductDelayPassUseOnExit()
        sql = const.SQL0373
    if listS[1] == 117 and listS[0] == 3:
        arrayS = dataList.TxnProductDelayPurseUseOnExit()
        sql = const.SQL0375
    if listS[1] == 32 and listS[0] == 1:
        arrayS = dataList.TxnCardDepositReceiptReverse()
        sql = const.SQL0120
    if listS[1] == 33 and listS[0] == 1:
        arrayS = dataList.TxnCardFeeReverse()
        sql = const.SQL0121
    ##Eric 20211113
    if listS[1] == 79 and listS[0] == 3:
        arrayS = dataList.TxnProductMultirideIssueReverse()
        sql = const.SQL034F
    if listS[1] == 80 and listS[0] == 3:
        arrayS = dataList.TxnProductPassIssueReverse()
        sql = const.SQL0350
    if listS[1] == 81 and listS[0] == 3:
        arrayS = dataList.TxnProductPurseIssueReverse()
        sql = const.SQL0351

    if arrayS is None or len(arrayS) == 0:
        # eric 20250122 test begin
        # print('listS[0] = ' + str(listS[0]) + ', listS[1] = ' + str(listS[1]))
        # log.error('未处理交易类型: %s' % str(listS[0])+","+str(listS[1]))
        # eric 20250122 test end
        return

    writerArrays = onceDataForDictArray(arrayS, file_dat, index)

    tempArray = copy.deepcopy(headData)
    tempArray.insert(0, fileName)
    tempArray = tempArray + writerArrays

    global current_target_path
    new_dir = os.path.join(current_target_path, dec_hex(listS[0]) + dec_hex(listS[1]) + "." + listS[2] + '.csv')
    flag = os.path.isfile(new_dir)
    file_csv = open(new_dir, 'a+', newline='', encoding="utf-8-sig")  # 创建/修改新文件
    file_csv_writer = csv.writer(file_csv)

    if not flag:
        nameArray = ["文件名"]  # , "数据包长度", "数据包类型", "设备类型", "线路",
        # "站点", "设备编号", "未知含义", "未知含义",
        # "未知含义", "未知含义", "未知含义",
        # "未知含义", "未知含义"]
        for dicts in arrayS:
            if isinstance(dicts["name"], str):
                nameArray.append(dicts["name"])
            else:
                for strSingle in dicts["name"]:
                    nameArray.append(strSingle)

        file_csv_writer.writerow(nameArray)
    del tempArray[1:14]
    file_csv_writer.writerow(tempArray)
    if sql:
        mysql_helper.execute(sql, tempArray)
        pass
    file_csv.close()


def analysisDataHead(data, beginIndex):
    # Eric 20241221 comment next one line of code
    # lenDat = data.read()


    arrayS = []

    data.seek(0 + beginIndex)
    lenData = data.read(2)
    lenThs = struct.unpack('>H', lenData)[0]
    arrayS.append(lenThs)

    data.seek(2 + beginIndex)
    typeData = data.read(2)
    b = str(binascii.b2a_hex(typeData), encoding="utf-8")
    arrayS.append(b)

    data.seek(4 + beginIndex)
    typeData = data.read(14)
    others = struct.unpack('>4B1I6B', typeData)
    for obj in others:
        arrayS.append(obj)
    return arrayS


def analysisOnceData(data, beginIndex, fileName):
    data.seek(0, 0)
    lenAll = data.read()
    if beginIndex >= len(lenAll):
        return

    while beginIndex < len(lenAll):
        headData = analysisDataHead(data, beginIndex)
        if headData[1] == "6002":
            listS = []
            # tempIndex = 0
            tempIndex = 18
            while (headData[0] - tempIndex) > 32:
                # data.seek(58 + beginIndex + 18 + tempIndex, 0)
                data.seek(58 + beginIndex + tempIndex, 0)
                typeData = data.read(8)
                typeTuple = struct.unpack('>2I', typeData)
                listS = list(typeTuple)

                # data.seek(7 + beginIndex + 18 + tempIndex, 0)
                data.seek(7 + beginIndex + tempIndex, 0)
                lenData = data.read(2)
                onceLen = struct.unpack('<H', lenData)[0]

                if onceLen == 0:
                    break

                # data.seek(3 + beginIndex + 18 + tempIndex, 0)
                data.seek(3 + beginIndex + tempIndex, 0)
                lenData = data.read(4)
                b = str(binascii.b2a_hex(lenData), encoding="utf-8")
                listS.append(b)
                # analysisForDict(listS, data, beginIndex + 18 + tempIndex, headData, fileName)
                analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
                tempIndex = tempIndex + onceLen
        elif headData[1] == "6003":

            # tempIndex = 0
            tempIndex = 18

            while (headData[0] - tempIndex) > 32:
                # data.seek(10 + beginIndex + 18 + tempIndex, 0)
                data.seek(10 + beginIndex + tempIndex, 0)
                typeData = data.read(2)
                typeTuple = struct.unpack('<2B', typeData)
                listS = list(typeTuple)

                # data.seek(7 + beginIndex + 18 + tempIndex, 0)
                data.seek(7 + beginIndex + tempIndex, 0)
                lenData = data.read(2)
                onceLen = struct.unpack('<H', lenData)[0]

                # data.seek(3 + beginIndex + 18 + tempIndex, 0)
                if onceLen == 0:
                    break
                data.seek(3 + beginIndex + tempIndex, 0)
                lenData = data.read(4)
                b = str(binascii.b2a_hex(lenData), encoding="utf-8")
                listS.append(b)

                # analysisForDict(listS, data, beginIndex + 18 + tempIndex, headData, fileName)
                analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
                tempIndex = tempIndex + onceLen

        elif headData[1] == "4001":

            # tempIndex = 0
            tempIndex = 18

            while (headData[0] - tempIndex) > 26:
                listS = [81, 9, fileName[14:22]]
                onceLen = 26

                # print("\n4001,"+str(listS[1]) +","+ str(listS[0])+";")

                # analysisForDict(listS, data, beginIndex + 18 + tempIndex, headData, fileName)
                analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
                tempIndex = tempIndex + onceLen

        elif headData[1] == "7004":

            # tempIndex = 0
            tempIndex = 18

            while (headData[0] - tempIndex) > 16:
                listS = [70, 4, fileName[14:22]]
                onceLen = 16

                # print("\n4001,"+str(listS[1]) +","+ str(listS[0])+";")

                analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
                tempIndex = tempIndex + onceLen

        elif headData[1] == "7005":

            # tempIndex = 0
            tempIndex = 18

            while (headData[0] - tempIndex) > 23:
                listS = [70, 5, fileName[14:22]]
                onceLen = 23

                # print("\n4001,"+str(listS[1]) +","+ str(listS[0])+";")

                analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
                tempIndex = tempIndex + onceLen

        beginIndex = headData[0] + 2 + beginIndex

    # analysisOnceData(data, headData[0] + 2 + beginIndex, fileName)


def analysisOnceData_6_line(data, beginIndex, fileName):
    # print(fileName)
    data.seek(0, 0)
    lenAll = data.read()
    if beginIndex >= len(lenAll):
        return

    data.seek(0)
    typeData = data.read(2)
    b = str(binascii.b2a_hex(typeData), encoding="utf-8")

    data.seek(2)
    typeData = data.read(2)
    data_count = int(str(binascii.b2a_hex(typeData), encoding="utf-8"))

    headData = [0, b, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    listS = []
    if headData[1] == "6002":

        # tempIndex = 0
        tempIndex = 5
        for i in range(data_count):
            # data.seek(58 + beginIndex + 18 + tempIndex, 0)
            data.seek(58 + beginIndex + tempIndex, 0)
            typeData = data.read(8)
            typeTuple = struct.unpack('>2I', typeData)
            listS = list(typeTuple)

            # data.seek(7 + beginIndex + 18 + tempIndex, 0)
            data.seek(7 + beginIndex + tempIndex, 0)
            lenData = data.read(2)
            onceLen = struct.unpack('<H', lenData)[0]

            if onceLen == 0:
                break

            # data.seek(3 + beginIndex + 18 + tempIndex, 0)
            data.seek(3 + beginIndex + tempIndex, 0)
            lenData = data.read(4)
            b = str(binascii.b2a_hex(lenData), encoding="utf-8")
            listS.append(b)
            # analysisForDict(listS, data, beginIndex + 18 + tempIndex, headData, fileName)
            analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
            tempIndex = tempIndex + onceLen

    # eric 20250122 增加交通部交通卡类型 6013
    #elif headData[1] == "6003":
    elif headData[1] == "6003" or headData[1] == "6013":

        # tempIndex = 0
        tempIndex = 5

        for i in range(data_count):
            # data.seek(10 + beginIndex + 18 + tempIndex, 0)
            data.seek(10 + beginIndex + tempIndex, 0)
            typeData = data.read(2)
            typeTuple = struct.unpack('<2B', typeData)
            listS = list(typeTuple)

            # data.seek(7 + beginIndex + 18 + tempIndex, 0)
            data.seek(7 + beginIndex + tempIndex, 0)
            lenData = data.read(2)
            onceLen = struct.unpack('<H', lenData)[0]

            # data.seek(3 + beginIndex + 18 + tempIndex, 0)
            if onceLen == 0:
                break
            data.seek(3 + beginIndex + tempIndex, 0)
            lenData = data.read(4)
            b = str(binascii.b2a_hex(lenData), encoding="utf-8")
            listS.append(b)

            # analysisForDict(listS, data, beginIndex + 18 + tempIndex, headData, fileName)
            analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
            tempIndex = tempIndex + onceLen

    elif headData[1] == "4001":

        # tempIndex = 0
        tempIndex = 5

        for i in range(data_count):
            listS = [81, 9, fileName[14:22]]
            onceLen = 26

            # print("\n4001,"+str(listS[1]) +","+ str(listS[0])+";")

            # analysisForDict(listS, data, beginIndex + 18 + tempIndex, headData, fileName)
            analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
            tempIndex = tempIndex + onceLen

    elif headData[1] == "7004":

        # tempIndex = 0
        tempIndex = 5

        for i in range(data_count):
            listS = [70, 4, fileName[14:22]]
            onceLen = 16

            # print("\n4001,"+str(listS[1]) +","+ str(listS[0])+";")

            analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
            tempIndex = tempIndex + onceLen

    elif headData[1] == "7005":

        # tempIndex = 0
        tempIndex = 5

        for i in range(data_count):
            listS = [70, 5, fileName[14:22]]
            onceLen = 23

            # print("\n4001,"+str(listS[1]) +","+ str(listS[0])+";")

            analysisForDict(listS, data, beginIndex + tempIndex, headData, fileName)
            tempIndex = tempIndex + onceLen

    elif headData[1] == "4012":
        # 4012-票房售票机结帐数据
        sql = const.SQL4012
        tempIndex = 5
        #读取数据从第6字节开始的29个字节
        HeaderArrays = onceDataForDictArray(dataList.BOMSettleDataHead(), data, tempIndex)
        #读取文件中的记录数所在字节 第29字节的2个字节
        tempIndex = tempIndex + 29
        data.seek(tempIndex)
        count = struct.unpack('>I', data.read(4))[0]
        tempIndex = tempIndex + 4
        #读取每条记录
        lenDat = 68
        for i in range(count):
            try:
                writerArrays = onceDataForDictArray(dataList.BOMSettleDataBody(), data, tempIndex + i * lenDat)
                writerArrays = HeaderArrays + writerArrays
                writerArrays.insert(0, fileName)
                #print('writerArrays:', writerArrays)
                if sql:
                    #print('sql=%s', sql)
                    mysql_helper.execute(sql, writerArrays)
                    pass

            except Exception as e:
                print(fileName)
                print(e)


def analysisFileForHead(source_path: object, target_path: object, line, typeStr, dbName) -> object:
    global current_target_path
    global file_list
    global log

    creatMysqlCon(dbName)

    logName = line + '#' + typeStr
    rq = time.strftime('%Y%m%d', time.localtime(time.time()))
    log = Log(logName, rq)
    file_list = []
    current_target_path = target_path
    get_all_file(source_path)
    for dir_path in file_list:
        _, files = os.path.split(dir_path)
        # dir_path = os.path.join(source_path, files)
        # 分离文件名和文件类型
        file_name = os.path.splitext(files)[0]  # 文件名
        file_type = os.path.splitext(files)[1]  # 文件类型
        # 2020-07-10 chenchao
        # if file_type != '.dat':
        #    file_type = '.dat'

        ignoreDataCount = 0
        # 将.dat文件转为.csv文件
        # if file_type == '.dat':  # 可切换为.xls等
        file_dat = open(dir_path, 'rb')  # 读取原文件
        try:
            analysisOnceData(file_dat, 0, file_name + file_type)
        except Exception as e:
            print(files)
            print(e)
        file_dat.close()

    global mysql_helper
    mysql_helper.closeCon()


def analysisFileForHead_6_line(source_path: object, target_path: object, line, typeStr, dbName) -> object:
    global current_target_path
    global file_list
    global log

    creatMysqlCon(dbName)

    logName = line + '#' + typeStr
    rq = time.strftime('%Y%m%d', time.localtime(time.time()))
    log = Log(logName, rq)
    file_list = []
    current_target_path = target_path
    get_all_file(source_path)
    for dir_path in file_list:
        _, files = os.path.split(dir_path)
        # dir_path = os.path.join(source_path, files)
        # 分离文件名和文件类型
        file_name = os.path.splitext(files)[0]  # 文件名
        file_type = os.path.splitext(files)[1]  # 文件类型
        # 2020-07-10 chenchao
        # if file_type != '.dat':
        #    file_type = '.dat'

        ignoreDataCount = 0
        # 将.dat文件转为.csv文件
        # if file_type == '.dat':  # 可切换为.xls等
        file_dat = open(dir_path, 'rb')  # 读取原文件
        try:
            analysisOnceData_6_line(file_dat, 0, file_name + file_type)
        except Exception as e:
            print(files)
            print(e)
        file_dat.close()

    global mysql_helper
    mysql_helper.closeCon()

# 解析acc对账文件数据
def analysisFileForHead_9_acc(source_path: object, target_path: object, line, typeStr, dbName, item_tuple) -> object:
    global current_target_path
    global file_list
    global log
    global mysql_helper
    creatMysqlCon(dbName)

    logName = line + '#' + typeStr
    rq = time.strftime('%Y%m%d', time.localtime(time.time()))
    log = Log(logName, rq)
    file_list = []
    current_target_path = target_path
    get_all_file(source_path)
    #print(item_tuple)
    for dir_path in file_list:
        _, files = os.path.split(dir_path)
        # dir_path = os.path.join(source_path, files)
        # 分离文件名和文件类型
        # 文件名类似：Stat.20241125.71000009.F101 / Stat.20241125.71000009.F202
        file_name = os.path.splitext(files)[0]  # 文件名
        file_type = os.path.splitext(files)[1]  # 文件类型
        # 判断是否属于要解析的类型
        #item_tuple = ("F101","F106","F107")
        #print(item_tuple)
        #print("file_type:%s"%file_type[1:5])
        if file_type[1:5] not in item_tuple:
            #print(file_name+file_type+'不在解析范围')
            log.error(file_name+file_type+'不在解析范围')
            continue
        # 判断数据类型
        array, sql, lenDat = judgerReconciliationDataType(file_type)
        #if len(array) == 0:
        if array is None or len(array) == 0:
            log.error('无对应类型fileType: %s的定义'%file_type)
            # print('fileName%s', file_name)
            continue

        #ignoreDataCount = 0
        count = 0

        file_dat = open(dir_path, 'rb')  # 读取原文件
        #读取数据传输头和对账信息头 38+12字节
        HeaderArrays,pindex = onceDataForDictValue(dataList.ReconciliationFileHeader(), file_dat, 1)
        for dicts in HeaderArrays:
            if dicts["name"] == "RecNum":
                count = int(dicts["value"])
                break

        #读取每条记录
        for i in range(count):
            try:
                #readFileOne(array, file_dat, i * lenDat, file_name, sql)
                writerArrays = onceDataForDictArray(array, file_dat, pindex + i * lenDat)
                writerArrays.insert(0, file_name+file_type)
                #print('writerArrays:', writerArrays)
                if sql:
                    #print('sql=%s', sql)
                    mysql_helper.execute(sql, writerArrays)
                    pass

            except Exception as e:
                print(file_name+file_type)
                print(e)
        file_dat.close()

    mysql_helper.closeCon()

